<?php

declare(strict_types=1);

namespace App\Repository;

use PDO;

final class PostRepository
{
    public function __construct(
        private PDO $pdo,
    ) {
        $this->ensureSeedData();
    }

    /**
     * @return list<array{id:int,title:string,body:string}>
     */
    public function all(): array
    {
        $statement = $this->pdo->query(
            'SELECT id, title, body FROM posts ORDER BY id',
        );

        /** @var list<array{id:int,title:string,body:string}> $rows */
        $rows = $statement->fetchAll();

        return $rows;
    }

    /**
     * @return array{id:int,title:string,body:string}|null
     */
    public function findById(int $id): array|null
    {
        $statement = $this->pdo->prepare(
            'SELECT id, title, body FROM posts WHERE id = :id',
        );
        $statement->bindValue(':id', $id, PDO::PARAM_INT);
        $statement->execute();

        /** @var array{id:int,title:string,body:string}|false $row */
        $row = $statement->fetch();

        return $row === false ? null : $row;
    }

    /**
     * @param non-empty-string $title
     * @param non-empty-string $body
     *
     * @return array{id:int,title:string,body:string}
     */
    public function create(string $title, string $body): array
    {
        $statement = $this->pdo->prepare(
            'INSERT INTO posts (title, body) VALUES (:title, :body) RETURNING id',
        );
        $statement->bindValue(':title', $title, PDO::PARAM_STR);
        $statement->bindValue(':body', $body, PDO::PARAM_STR);
        $statement->execute();

        /** @var int|string $id */
        $id = $statement->fetchColumn();

        return $this->findById((int) $id);
    }

    private function ensureSeedData(): void
    {
        $count = (int) $this->pdo->query('SELECT COUNT(*) FROM posts')->fetchColumn();
        if ($count > 0) {
            return;
        }

        $statement = $this->pdo->prepare(
            'INSERT INTO posts (title, body) VALUES (:title, :body)',
        );

        foreach ($this->seedPosts() as $post) {
            $statement->execute($post);
        }
    }

    /**
     * @return list<array{title:string,body:string}>
     */
    private function seedPosts(): array
    {
        return [
            ['title' => 'Hello from SQLite', 'body' => 'A starter post loaded from the database seed.'],
            ['title' => 'Second Entry', 'body' => 'This record shows how to extend the seed set.'],
        ];
    }
}
